import win32gui, win32con, win32api
from PIL import Image, ImageGrab, ImageChops
from EnumWindowsHelper import EnumWindowsHelper
import time
import numpy as np
import cv2


'''

直径32
54 9
54+32*19=54+608
9+608

位置计算：round（（位置X-54）/ 32） 四舍五入 得 x 从0开始计
         round（（位置y-9）/ 32） 四舍五入 得 y 从0开始计
截取
'''
class YeHuUiHelper:
    def __init__(self):
        self.hwnds = {'main_hwnd': 0, 'board_hwnd': 0 }
        self.svm_model=cv2.ml.SVM_load('svm_model.xml')
        self.findWindowHelper=EnumWindowsHelper()

    def FindMainBoard(self):
        hwnds=self.findWindowHelper.EnumYeHuWindows('> [高级房', 'CChessboardPanel')
        if hwnds['board_hwnd']>0:
            self.hwnds=hwnds
        return hwnds

    def FindRecBoard(self):
        hwnds=self.findWindowHelper.EnumYeHuWindows('野狐围棋 > 记谱', 'CChessboardPanel')
        if hwnds['board_hwnd']>0:
            self.hwnds=hwnds
        return hwnds
    
    def CutBoard(self, _img):
        img = cv2.cvtColor(np.asarray(_img),cv2.COLOR_RGB2BGR)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        ret,thresh = cv2.threshold(gray,126,255,0)
        contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, 2)
        maxArea = 0
        maxCnt = None
        for cnt in contours:
            a = cv2.contourArea(cnt)
            if a>maxArea:
                maxArea=a
                maxCnt=cnt
        x, y, w, h = cv2.boundingRect(maxCnt)
        cropped = gray[y:y+h, x:x+w] ## 裁剪坐标为[y0:y1, x0:x1]
        return cropped, x, y, w, h

    def Recognition(self):
        if not self.YeHuWindowsInitOk():
            print('没有初始化')
            return
        _img = self.CutBoardScreen()
        cropped, x, y, w, h = self.CutBoard(_img)
        self.setBoardPos(x, y, w, h)

        if w!=h:
            raise Exception('截图尺寸不对！：'+str(w)+':'+str(h))
        #cropped=cv2.resize(cropped, (611, 611))
        if w!=611:
            cropped.resize((611, 611))
            print(cropped.shape)
        
        test_data=[]
        for py in range(19):
            y=py*32+1
            for px in range(19):
                x=px*32+1
                cimg=cropped[y:y+32, x:x+32]
                test_data.append(cimg)
        test_data = np.array(test_data)
        test_data = test_data.astype(np.float32)
        test_data = test_data.reshape((test_data.shape[0], -1))
        # 进行预测
        _, test_labels = self.svm_model.predict(test_data)
        board=test_labels.reshape((19, 19))
        
        return board


    def setBoardPos(self, x, y, w, h):
        self.board_x = x
        self.board_y = y
        self.board_w = w
        self.board_h = h

    def YeHuWindowsInitOk(self):
        return self.hwnds['board_hwnd']>0 and win32gui.IsWindowVisible(self.hwnds['board_hwnd'])>0


    def SetYeHuWindowPos(self):
        if self.YeHuWindowsInitOk():
            desktop_hwnd = win32gui.GetDesktopWindow()
            x1, y1, x2, y2 = win32gui.GetWindowRect(desktop_hwnd)
            w = x2-x1
            win32gui.SetForegroundWindow(self.hwnds['main_hwnd'])
            win32gui.SetWindowPos(self.hwnds['main_hwnd'], win32con.HWND_TOPMOST, 0, 0, 0, 0, 0)
            #x1, y1, x2, y2 = win32gui.GetWindowRect(hwnds['main_hwnd'])
            win32gui.MoveWindow(self.hwnds['main_hwnd'], int(w/2), 0, 1180, 728,False)


    def CutBoardScreen(self):
        if self.YeHuWindowsInitOk():
            x1, y1, x2, y2 = win32gui.GetWindowRect(self.hwnds['board_hwnd'])
            #m_pos = win32api.GetCursorPos()
            #win32api.SetCursorPos([0,0])
            img_ready = ImageGrab.grab((x1, y1, x2, y2))
            #win32api.SetCursorPos(m_pos)
            return img_ready
        return None
    
    def MouseClick(self, x, y): #第三种，可后台
        handle=self.hwnds['board_hwnd']
        k = int(self.board_w / 19)
        k2 = int(k/2)
        client_pos =(x*k+self.board_x+k2,y*k+self.board_y+k2)
        tmp=win32api.MAKELONG(client_pos[0],client_pos[1])
        win32gui.SendMessage(handle, win32con.WM_ACTIVATE,win32con.WA_ACTIVE,0)
        win32gui.SendMessage(handle, win32con.WM_LBUTTONDOWN,win32con.MK_LBUTTON,tmp)
        win32gui.SendMessage(handle, win32con.WM_LBUTTONUP,win32con.MK_LBUTTON,tmp)

    def MouseClick2(self, x, y):
        m_pos = win32api.GetCursorPos()
        x1, y1, x2, y2 = win32gui.GetWindowRect(self.hwnds['board_hwnd'])
        win32gui.SetForegroundWindow(self.hwnds['main_hwnd'])
        k = int(self.board_w / 19)
        k2 = int(k/2)
        win32api.SetCursorPos([x*k+self.board_x+k2+x1,y*k+self.board_y+k2+y1])
        time.sleep(0.1)
        #执行左单键击，若需要双击则延时几毫秒再点击一次即可
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
        time.sleep(0.1)
        win32api.SetCursorPos(m_pos)


    def SendNextEven(self):
        #win32gui.SetForegroundWindow(self.hwnds['main_hwnd'])
        win32gui.SetActiveWindow(self.hwnds['main_hwnd'])
        #win32gui.SendMessage(self.hwnds['main_hwnd'], win32con.WM_KEYDOWN, win32con.VK_RIGHT, 0)
        #win32gui.SendMessage(self.hwnds['main_hwnd'], win32con.WM_KEYUP, win32con.VK_RIGHT, 0)
        win32api.keybd_event(39, 0, 0, 0) 
        win32api.keybd_event(39, 0, win32con.KEYEVENTF_KEYUP, 0)


if __name__ == '__main__':
    helper = YeHuUiHelper()
    helper.FindRecBoard()
    if helper.YeHuWindowsInitOk():
        board=helper.Recognition()
        print(board)


